home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 1.iso / HENSA / MATHS / PLPLOT / PLPLOT.ZIP / sys / dos / bcc / win3.c < prev   
Encoding:
C/C++ Source or Header  |  1994-08-10  |  9.4 KB  |  392 lines

  1. /*
  2.   win3.c
  3.  
  4.   Paul Casteels
  5.   09-May-1994
  6.   casteels@uia.ac.be
  7.  
  8.   A driver for Windows 3.x
  9.  
  10. */
  11. #ifdef WIN3
  12.  
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include "plplotP.h"
  16. #include "drivers.h"
  17. #include <windows.h>
  18. //#define NDEBUG
  19. #include <assert.h>
  20. #include "plplot.rc"
  21.  
  22. #define TEXT_MODE 0
  23. #define GRAPHICS_MODE 1
  24.  
  25.  
  26. #define CLEAN 0
  27. #define DIRTY 1
  28.  
  29. const float xRes = 8192,yRes = 8192;
  30. const int niceCnt = 20;
  31. const char szPlPlotClass[] = "PlplotClass";
  32. const char szPlPlotWName[] = "PlPlot Window";
  33. const char aboutText[] = "        Plplot    "PLPLOT_VERSION
  34.                                 "\nComments/Questions to\n"
  35.                                 "plplot-list@dino.ph.utexas.edu\n";
  36.  
  37. LRESULT CALLBACK _export PlPlotWndProc (HWND hwnd,UINT message,
  38.   UINT wParam,LONG lParam);
  39.  
  40. typedef struct {
  41.   HWND hwnd;
  42.   HMENU hMenu;
  43.   HPEN hPen;
  44.   HDC hdc;
  45.   float xScale,yScale;
  46.   int nextPlot;    // set to 1 by Nextplot menu
  47.   int nice;            // be nice for windows multitasking
  48.   int rePaint;        // if the background is cleared we need a repaint
  49.   int rePaintBsy;    // if we are repainting block the rest
  50.                         // plRemakePlot is not reentrant (in Windows)?
  51.   int newCursor;
  52.   float cursorX,cursorY;
  53. } WinDev;
  54.  
  55. MSG msg;
  56. long colors[16]={
  57.   RGB(0,0,0),        // 0 = black
  58.   RGB(0,0,255),    // 1 = blue
  59.   RGB(0,255,0),    // 2 = green
  60.   RGB(0,255,255),    // 3 = cyan
  61.   RGB(255,0,0),    // 4 = red
  62.   RGB(255,0,255),    // 5 = magenta
  63.   RGB(255,255,0),    // 6 = yellow
  64.   RGB(255,255,255),    // 7 = white
  65.   RGB(0,0,0),
  66.   RGB(0,0,0),
  67.   RGB(0,0,0),
  68.   RGB(0,0,0),
  69.   RGB(0,0,0),
  70.   RGB(0,0,0),
  71.   RGB(0,0,0),
  72.   RGB(0,0,0)};
  73.  
  74. // Transfer control to windows
  75. void checkMessage() {
  76.   if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) {
  77.      TranslateMessage(&msg);
  78.      DispatchMessage(&msg);
  79.   }
  80. }
  81.  
  82. // Simplest way to connect to a printer
  83. HDC GetPrinterDC () {
  84.   char szPrinter[80];
  85.   char *szDevice,*szDriver,*szOutput;
  86.   GetProfileString("windows","device",",,,",szPrinter,80);
  87.   if (NULL != (szDevice = strtok(szPrinter,"," )) &&
  88.         NULL != (szDriver = strtok(NULL,     ", ")) &&
  89.         NULL != (szOutput = strtok(NULL,     ", ")))
  90.      return CreateDC(szDriver,szDevice,szOutput,NULL);
  91.   return 0;
  92. }
  93.  
  94. /*----------------------------------------------------------------------*\
  95. * Initialize device.
  96. \*----------------------------------------------------------------------*/
  97.  
  98. void
  99. plD_init_win3(PLStream *pls)
  100. {
  101.      HWND   hwndMain;
  102.      WNDCLASS wndclass;
  103.      HANDLE hInstance;
  104.  
  105.      WinDev *dev;
  106.      int xPos,yPos;
  107.      int nWidth,nHeight;
  108.  
  109.      pls->termin = 1;            // is an interactive terminal
  110.      pls->icol0 = 1;            // current color
  111.      pls->width = 1;            // current pen width
  112.      pls->bytecnt = 0;
  113.      pls->page = 0;
  114.      pls->plbuf_write = 1;    // buffer the output
  115.      pls->dev_flush = 1;        // flush as we like
  116.  
  117. /* Set up device parameters */
  118.      if (pls->dev != NULL)
  119.         delete pls->dev;
  120.      pls->dev = new WinDev;
  121.      assert(pls->dev != NULL);
  122.      dev = (WinDev *) pls->dev;
  123.      dev->nextPlot = 0;
  124.      dev->nice = 0;
  125.      dev->hPen = CreatePen(PS_SOLID,0,colors[0]);
  126.  
  127. // Get/save this from plplot.ini ??
  128.      xPos = 100;
  129.      yPos = 100;
  130.      nWidth = 600;
  131.      nHeight = 400;
  132.  
  133.      hwndMain = GetActiveWindow();
  134.      hInstance = GetWindowWord(hwndMain,GWW_HINSTANCE);
  135.      dev->hMenu = LoadMenu(hInstance,"COMMANDS");
  136.  
  137.      wndclass.style = CS_HREDRAW | CS_VREDRAW;
  138.      wndclass.lpfnWndProc = ::PlPlotWndProc;
  139.      wndclass.cbClsExtra = 0;
  140.      wndclass.cbWndExtra = sizeof(pls);
  141.      wndclass.hInstance = hInstance;
  142.      wndclass.hIcon = LoadIcon(hInstance,"PLICON");
  143.      wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);
  144.      wndclass.hbrBackground = GetStockObject(WHITE_BRUSH);
  145.      wndclass.lpszMenuName = NULL;
  146.      wndclass.lpszClassName = szPlPlotClass;
  147.      RegisterClass (&wndclass);
  148.  
  149.      dev->hwnd = CreateWindow(szPlPlotClass,szPlPlotWName,
  150.         WS_OVERLAPPEDWINDOW,
  151.         xPos,yPos,nWidth,nHeight,
  152.         NULL,dev->hMenu,
  153.         hInstance,NULL);
  154.  
  155.      SetWindowLong(dev->hwnd,0,(long)pls);
  156.  
  157.      ShowWindow(dev->hwnd,SW_SHOW);
  158.  
  159.      plP_setpxl(2.5,2.5);           /* Pixels/mm. */
  160.      plP_setphy(0,xRes,0,yRes);
  161. }
  162.  
  163. /*----------------------------------------------------------------------*\
  164. * line()
  165. *
  166. * Draw a line in the current color from (x1,y1) to (x2,y2).
  167. \*----------------------------------------------------------------------*/
  168.  
  169. void
  170. plD_line_win3(PLStream *pls, short x1a, short y1a, short x2a, short y2a)
  171. {
  172.   WinDev *dev = (WinDev *)pls->dev;
  173.   SelectObject(dev->hdc,dev->hPen);
  174.   MoveTo(dev->hdc,x1a * dev->xScale,(yRes - y1a) * dev->yScale);
  175.   LineTo(dev->hdc,x2a * dev->xScale,(yRes - y2a) * dev->yScale);
  176.   if (!dev->rePaintBsy)
  177.      if (dev->nice++ > niceCnt) {
  178.         dev->nice = 0;
  179.         checkMessage();
  180.      }
  181. }
  182.  
  183. /*----------------------------------------------------------------------*\
  184. * bgi_polyline()
  185. *
  186. * Draw a polyline in the current color.
  187. \*----------------------------------------------------------------------*/
  188.  
  189. void
  190. plD_polyline_win3(PLStream *pls, short *xa, short *ya, PLINT npts)
  191. {
  192.   WinDev *dev = (WinDev *)pls->dev;
  193.   SelectObject(dev->hdc,dev->hPen);
  194.   MoveTo(dev->hdc,xa[0] * dev->xScale,(yRes - ya[0]) * dev->yScale);
  195.   for (int i=1;i<npts;i++) {
  196.      LineTo(dev->hdc,xa[i] * dev->xScale,(yRes - ya[i]) * dev->yScale);
  197.   }
  198.   if (!dev->rePaintBsy) {
  199.      dev->nice = 0;
  200.      checkMessage();
  201.   }
  202. }
  203.  
  204. /*----------------------------------------------------------------------*\
  205. * bgi_eop()
  206. *
  207. * End of page.
  208. \*----------------------------------------------------------------------*/
  209.  
  210. void
  211. plD_eop_win3(PLStream *pls)
  212. {
  213.   WinDev *dev = (WinDev *)pls->dev;
  214.  
  215.   ReleaseDC(dev->hwnd,dev->hdc);
  216.   EnableMenuItem(dev->hMenu,CM_PRINTPLOT,MF_ENABLED);
  217.   EnableMenuItem(dev->hMenu,CM_NEXTPLOT,MF_ENABLED);
  218.   while (!dev->nextPlot) {
  219.      GetMessage(&msg,NULL,0,0);
  220.      TranslateMessage(&msg);
  221.      DispatchMessage(&msg);
  222.   }
  223.   InvalidateRect(dev->hwnd,NULL,TRUE);
  224.   UpdateWindow(dev->hwnd);
  225.   dev->nextPlot = 0;
  226. }
  227.  
  228. /*----------------------------------------------------------------------*\
  229. * bop()
  230. *
  231. * Set up for the next page.
  232. * Advance to next family file if necessary (file output).
  233. \*----------------------------------------------------------------------*/
  234.  
  235. void
  236. plD_bop_win3(PLStream *pls)
  237. {
  238.   WinDev *dev = (WinDev *)pls->dev;
  239.   RECT rect;
  240.  
  241.   EnableMenuItem(dev->hMenu,CM_PRINTPLOT,MF_GRAYED);
  242.   EnableMenuItem(dev->hMenu,CM_NEXTPLOT,MF_GRAYED);
  243.  
  244.   dev->hdc = GetDC(dev->hwnd);
  245.   GetClientRect(dev->hwnd,&rect);
  246.   dev->xScale = rect.right / (xRes + 1);
  247.   dev->yScale = rect.bottom / (yRes + 1);
  248.  
  249.   dev->rePaint = 0;
  250.   dev->rePaintBsy = 0;
  251.   dev->nice = 0;
  252.   pls->page++;
  253. }
  254.  
  255. /*----------------------------------------------------------------------*\
  256. * bgi_tidy()
  257. *
  258. * Close graphics file or otherwise clean up.
  259. \*----------------------------------------------------------------------*/
  260.  
  261. void
  262. plD_tidy_win3(PLStream *pls)
  263. {
  264.   WinDev *dev = (WinDev *)pls->dev;
  265.  
  266.   pls->page = 0;
  267.   pls->OutFile = NULL;
  268.   DestroyWindow(dev->hwnd);
  269. }
  270.  
  271. void plD_state_win3(PLStream *pls,PLINT op) {
  272.   WinDev *dev = (WinDev *)pls->dev;
  273.  
  274.   switch(op) {
  275.   case PLSTATE_WIDTH:
  276.      break;
  277.   case PLSTATE_COLOR0:
  278.      DeleteObject(dev->hPen);
  279.      dev->hPen = CreatePen(PS_SOLID,0,colors[(int)pls->icol0]);
  280.      break;
  281.   }
  282. }
  283.  
  284.  
  285. /*----------------------------------------------------------------------*\
  286. * bgi_esc()
  287. *
  288. * Escape function.
  289. \*----------------------------------------------------------------------*/
  290.  
  291. void
  292. plD_esc_win3(PLStream *pls, PLINT op , void *ptr)
  293. {
  294.   WinDev *dev = (WinDev *)pls->dev;
  295.   HCURSOR holdcursor,hnewcursor;
  296.  
  297.   if (op == PLESC_GETC) {
  298.      hnewcursor = LoadCursor(NULL,IDC_CROSS);
  299.      holdcursor = GetClassWord(GetActiveWindow(),GCW_HCURSOR);
  300.      SetCursor(hnewcursor);
  301.      SetClassWord(GetActiveWindow(),
  302.                       GCW_HCURSOR,
  303.                       hnewcursor);
  304.      dev->newCursor = 0;
  305.      while (!dev->newCursor)
  306.         checkMessage();
  307.      ((PLCursor *)ptr)->vpX = dev->cursorX;
  308.      ((PLCursor *)ptr)->vpY = dev->cursorY;
  309.      SetClassWord(GetActiveWindow(),
  310.                       GCW_HCURSOR,
  311.                       holdcursor);
  312.   }
  313. }
  314.  
  315. LRESULT CALLBACK _export PlPlotWndProc (HWND hwnd,UINT message,
  316.   UINT wParam,LONG lParam)
  317. {
  318.   RECT rect;
  319.   PAINTSTRUCT ps;
  320.   PLStream *pls = (PLStream *)GetWindowLong(hwnd,0);
  321.   WinDev *dev = NULL;
  322.   HCURSOR hcurSave;
  323.  
  324.   if (pls)
  325.      dev = (WinDev *)pls->dev;
  326.  
  327.   switch (message) {
  328.      case WM_RBUTTONDOWN :
  329.         dev->newCursor = 1;
  330.         dev->cursorX = LOWORD(lParam) / dev->xScale;
  331.         dev->cursorY = yRes - HIWORD(lParam) / dev->yScale;
  332.         return 0;
  333.      case WM_ERASEBKGND :
  334.         if (!dev->rePaintBsy)
  335.           dev->rePaint = 1;
  336.         break;
  337.      case WM_PAINT :
  338.         if (dev) {
  339.           if (dev->rePaint) {
  340.              dev->rePaint = 0;
  341.              dev->rePaintBsy = 1;
  342.              hcurSave = SetCursor(LoadCursor(NULL,IDC_WAIT));
  343.              dev->hdc = GetDC(dev->hwnd);
  344.              GetClientRect(dev->hwnd,&rect);
  345.              dev->xScale = rect.right / (xRes + 1);
  346.              dev->yScale = rect.bottom / (yRes + 1);
  347.              plRemakePlot(pls);
  348.              dev->rePaintBsy = 0;
  349.              SetCursor(hcurSave);
  350.              ReleaseDC(dev->hwnd,dev->hdc);
  351.           }
  352.           BeginPaint(hwnd,&ps);
  353.           EndPaint(hwnd,&ps);
  354.           return 0;
  355.         }
  356.         break;
  357.      case WM_DESTROY :
  358. //        PostQuitMessage(0);
  359.         return 0;
  360.      case WM_COMMAND :
  361.         switch (wParam) {
  362.           case  CM_NEXTPLOT :
  363.              if (dev)
  364.                 dev->nextPlot = 1;
  365.              return 0;
  366.           case CM_PRINTPLOT :
  367.              dev->rePaintBsy = 1;
  368.              dev->hdc = GetPrinterDC();
  369.              dev->xScale = GetDeviceCaps(dev->hdc,HORZRES) / (xRes + 1);
  370.              dev->yScale = GetDeviceCaps(dev->hdc,VERTRES) / (yRes + 1);
  371.              Escape(dev->hdc,STARTDOC,0,NULL,NULL);
  372.              hcurSave = SetCursor(LoadCursor(NULL,IDC_WAIT));
  373.              plRemakePlot(pls);
  374.              Escape(dev->hdc,NEWFRAME,0,NULL,NULL);
  375.              Escape(dev->hdc,ENDDOC,0,NULL,NULL);
  376.              SetCursor(hcurSave);
  377.              dev->rePaintBsy = 0;
  378.              DeleteDC(dev->hdc);
  379.              return 0;
  380.           case CM_ABOUT :
  381.              MessageBox(hwnd,aboutText,"About",MB_OK);
  382.              return 0;
  383.         }
  384.   }
  385.   return DefWindowProc(hwnd,message,wParam,lParam);
  386. }
  387. #else
  388. pldummy_win3() {
  389.   return 0;
  390. }
  391. #endif //WIN3
  392.